/*
  使用快速排序法求第 k 小的数
  题目描述
    使用快速排序的方法，实现对 a 数组下标 l∼r 之间的元素寻找第 k 小的功能。
  输入格式
    输入共 3 行。
    第一行输入一个整数 n，表示序列的长度。
    第二行输入 n 个整数，对应 a[1] ~ a[n] 之间的 n 个整数。
    第三行输入三个整数, 对应 l, r, k。
  输出格式
    输出一个整数，表示数组 a 小标 l~r 之间的元素中第 k 小的数。
  输入数据 1
    5
    15 2 67 3 12
    1 3 2
  输出数据 1
    2
*/

#include <bits/stdc++.h>

using namespace std;

int a[10010];

/*
  使用快速排序的方法，实现对整形数组 a 的下标 s∼e 之间的元素寻找第 k 小的数
  返回值为一个整型数，为寻找到的第 k 小的数
  说明:
    1). 快速排序是分治算法的一种应用。分支算法通常使用递归的方法编码
    2). 算法复杂度对比
          快速排序排序法，对 n 个数进行排序的算法复杂度为 O(nlong(n))
          使用快速排序法，求第 k 小的数的算法复杂度为 O(n)；
*/
int kp_kx(int s, int e, int k) {
    if (s == e) {
        return a[s];
    }

    int i = s;     // 左指针
    int j = e;     // 右指针
    int x = a[i];  // 基准值
    while (i <= j) {
		    // 左指针从左往右，查找第一个 "目前在左半部分但应属于右半部分的数"
        while (i <= j && a[i] < x) { // 注意: 这里将等于"基准值"的数也移到另一部分!
            i++;
        }
		    // 右指针从右往左，查找第一个 "目前在右半部分但应属于左半部分的数"
        while (i <= j && a[j] > x) { // 注意: 这里将等于"基准值"的数也移到另一部分!
            j--;
        }
        if (i <= j) {  // 表明已经找到需要交换的一对数!
			      // 将 "目前在左半部分但应属于右半部分的数" 和 "目前在右半部分但应属于左半部分的数" 进行互换
            swap(a[i], a[j]);
            i++;
            j--;
        }
    }
    if (e - i + 1 >= k) {  // 要求的数在右半部分，继续在右半部分用快速排序法寻找第 k 小的数
        return kp_kx(i, e, k);
    } else {               // 要求的数在左半部分，继续在左半部分用快速排序法寻找第 k - (e - i + 1) 小的数
        return kp_kx(s, j, k - (e - i + 1));
    }
}

int main() {
    int n;
    int s;
    int e;
    int k;

    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }

    cin >> s >> e >> k;
    kp_kx(s, e, k);

    for (int i = 1; i <= n; i++) {
        cout << a[i] << " ";
    }

    return 0;
}